home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (c) 1992 The Geometry Center; University of Minnesota
- 1300 South Second Street; Minneapolis, MN 55454, USA;
-
- This file is part of geomview/OOGL. geomview/OOGL is free software;
- you can redistribute it and/or modify it only under the terms given in
- the file COPYING, which you should have received along with this file.
- This and other related software may be obtained via anonymous ftp from
- geom.umn.edu; email: software@geom.umn.edu. */
-
- /* Authors: Charlie Gunn, Stuart Levy, Tamara Munzner, Mark Phillips */
-
- #include "string.h"
- #include "geomclass.h"
- #include <stdarg.h>
-
- static struct extmethods {
- char *methodname;
- GeomExtFunc *defaultfunc;
- } *extmethods = NULL;
-
- static int n_extmethods = 1, max_extmethods = 0;
-
- int
- GeomMethodSel(char *methodname)
- {
- register struct extmethods *m;
- register int i;
-
- for(i = 1; i < n_extmethods; i++)
- if((m = &extmethods[i])->methodname != NULL &&
- strcmp(m->methodname, methodname) == 0)
- return i;
- return 0;
- }
-
- int
- GeomNewMethod(char *methodname, GeomExtFunc *defaultfunc)
- {
- register struct extmethod *m;
- register int sel;
- int oldmax = max_extmethods;
-
- sel = GeomMethodSel(methodname);
- if(sel > 0)
- return 0;
- sel = n_extmethods++;
- if(sel >= oldmax) {
- extmethods = (oldmax == 0)
- ? OOGLNewNE(struct extmethods, (max_extmethods = 7),
- "Extension methods")
- : OOGLRenewNE(struct extmethods, extmethods, (max_extmethods *= 2),
- "Extension methods");
- bzero(&extmethods[oldmax],
- (max_extmethods - oldmax) * sizeof(struct extmethods));
- }
- extmethods[sel].defaultfunc = defaultfunc;
- extmethods[sel].methodname = strdup(methodname);
- return sel;
- }
-
- char *
- GeomMethodName(int sel)
- {
- struct extmethods *m;
-
- return (sel <= 0 || sel >= n_extmethods)
- ? NULL : extmethods[sel].methodname;
- }
-
- GeomExtFunc *
- GeomSpecifyMethod( int sel, GeomClass *Class, GeomExtFunc *func )
- {
- int oldmax;
- int need;
- GeomExtFunc *oldfunc;
-
- if(Class == NULL || sel <= 0 || sel >= n_extmethods)
- return NULL;
-
- oldmax = Class->n_extensions;
- if(sel >= oldmax) {
- need = (oldmax == 0) ? 7 : oldmax*2;
- if(need <= sel) need = sel+1;
- Class->extensions = (oldmax == 0)
- ? OOGLNewNE(GeomExtFunc *,
- need, "Extension func vector")
- : OOGLRenewNE(GeomExtFunc *, Class->extensions,
- need, "Extension func vector");
- Class->n_extensions = need;
- bzero(&Class->extensions[oldmax],
- (need - oldmax) * sizeof(GeomExtFunc *));
- }
- oldfunc = Class->extensions[sel];
- Class->extensions[sel] = func;
- return oldfunc;
- }
-
- void *
- GeomCall(int sel, Geom *geom, ...)
- {
- register GeomClass *C;
- register GeomExtFunc *ext = NULL;
- void *result = NULL;
- va_list args;
-
- if(geom == NULL || sel <= 0 || sel >= n_extmethods)
- return NULL;
-
- C = geom->Class;
- while(sel >= C->n_extensions || (ext = C->extensions[sel]) == NULL) {
- if((C = C->super) == NULL) {
- ext = extmethods[sel].defaultfunc;
- break;
- }
- }
- if(ext) {
- va_start(args, geom);
- result = (*ext)(sel, geom, args);
- va_end(args);
- }
- return result;
- }
-
- void *
- GeomCallV(int sel, Geom *geom, va_list args)
- {
- register GeomClass *C;
- register GeomExtFunc *ext = NULL;
-
- if(geom == NULL || sel <= 0 || sel >= n_extmethods)
- return NULL;
-
- C = geom->Class;
- while(sel >= C->n_extensions || (ext = C->extensions[sel]) == NULL) {
- if((C = C->super) == NULL) {
- ext = extmethods[sel].defaultfunc;
- break;
- }
- }
- return ext ? (*ext)(sel, geom, args) : NULL;
- }
-